using UnityEngine;
using System.Collections;
using System.Linq;
using System.Text;
using System;
using System.Collections.Generic;
using LogicalComponent.util;
using LogicalComponent.rules.grid;
using LogicalComponent.userInterface;

public class MoveUtil : MonoBehaviour {

    public interface Mover
    {
        void DoMove(float timePassed);
        void SetDestination(Coordinate c);
    }

    public static void Teleport(Coordinate c, Transform t)
    {
        Tile tile = UiUtil.GetTile(c);
        if (tile != null)
        {
            t.position = tile.GetPawnPosition();
        }
    }

    public static float MoveTowards(Coordinate c, Transform t, float speed, float time)
    {
        Tile tile = UiUtil.GetTile(c);
        Vector3 tilePosition = tile.GetPawnPosition();
        Vector3 source = t.position;
        Vector3 totalMove = GetFlatVectorBetween(source, tilePosition);

        float distanceToGo = totalMove.magnitude;
        float moveMagnitude = (speed * time);
        float leftOverDistance = distanceToGo - moveMagnitude;
        if (leftOverDistance <= 0)
        {
            t.position = tilePosition;
            return - leftOverDistance / speed;
        }

        totalMove.Normalize();
        totalMove.Scale(new Vector3(moveMagnitude, moveMagnitude, moveMagnitude));
        Vector3 yChange = new Vector3(0, (tilePosition.y - source.y) * moveMagnitude / distanceToGo, 0);
        t.position = source + totalMove + yChange;

        return 0;
    }

    public static Vector3 GetFlatVectorBetween(Vector3 source, Vector3 destination)
    {
        Vector3 diff = destination - source;
        diff.Scale(new Vector3(1, 0, 1));
        return diff;
    }

    public static int MoveAlong(Path path, int nextStep, Transform t, float speed, float time)
    {
        float timeLeft = time;
        while (timeLeft > 0 && nextStep < path.Length)
        {
            Coordinate destination = path.GetCoordinate(nextStep);
            timeLeft = MoveTowards(destination, t, speed, timeLeft);
            if (timeLeft > 0)
            {
                nextStep++;
            }
        }
        return nextStep;
    }
}
